import com.sun.deploy.security.ValidationState;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Type;

import java.io.IOException;

import static org.objectweb.asm.Opcodes.*;

/**visit类的信息
 * param	            参数	            示例	                                        解释
 int version	        版本号	        V1_5	                                    1.5版本
 int access	        访问标志	        ACC_PUBLIC + ACC_ABSTRACT + ACC_INTERFACE	公有抽象接口类
 String name	        类的全限定名称	“pkg/Comparable”	                        Comparable类名
 String signature	泛型签名	        null
 String superName	父类	            “java/lang/Object”	                        父类是Object
 String[] interfaces	接口	            new String[] { “pkg/Mesurable” }	        实现该接口
 *
 * */

/**visitField成员变量的信息
 *
 *     param	            参数	            示例	                                        解释
 *     int access	    访问标志	        ACC_PUBLIC + ACC_FINAL + ACC_STATIC	        公有静态变量
 *     String name	    类的全限定名称	    “pkg/Comparable”	                        Comparable变量名
 *     String descriptor	变量类型	        I                                           int型的变量
 *     String signature	泛型	            null	                                    没有使用泛型
 *     Object value	    常量	            new Object	                                (疑似)必须是常量方法才可以使用
 * */

/**visitMethod方法的信息
 *
 *    param	            参数	            示例	                                        解释
 *    int access	    访问标志	        ACC_PUBLIC + ACC_ABSTRACT + ACC_INTERFACE	公有抽象接口方法
 *    String name	    类的全限定名称	    “pkg/Comparable”	                        Comparable方法名
 *    String descriptor 变量类型	        (Ljava/lang/Object;)I                       有一个object的参数，返回值为int
 *    String signature	泛型	            null	                                    没有使用泛型
 *    String[] value	方法抛出的异常	    null	                                    方法没有抛出异常
 * */
public class AsmWriter2 {

    public static void main(String[] args) throws IllegalAccessException, InstantiationException, IOException {
/***经典案列
        ClassWriter cw = new ClassWriter(0);
        cw.visit(V1_5, ACC_PUBLIC + ACC_ABSTRACT + ACC_INTERFACE, "pkg/Comparable", null, "java/lang/Object",null);

        cw.visitField(ACC_PUBLIC + ACC_FINAL + ACC_STATIC, "LESS", "I", null, new Integer(-1)).visitEnd();

        cw.visitField(ACC_PUBLIC + ACC_FINAL + ACC_STATIC, "EQUAL", "I", null, new Integer(0)).visitEnd();

        cw.visitField(ACC_PUBLIC + ACC_FINAL + ACC_STATIC, "GREATER", "I", null, new Integer(1)).visitEnd(); cw.visitMethod(ACC_PUBLIC + ACC_ABSTRACT, "compareTo", "(Ljava/lang/Object;)I", null, null).visitEnd();

        cw.visitEnd();

         byte[] b = cw.toByteArray();

         MyClassLoader my = new MyClassLoader();
         Class c = my.defineClass("pkg.Comparable",b);
         AsmReader.reader(b);
         System.out.println(c.getMethods()[0].getName());

 */

        ClassWriter cw = new ClassWriter(0);
        cw.visit(V1_8, ACC_PUBLIC, "Comparable", null, "java/lang/Object",null);

        cw.visitField(ACC_PUBLIC, "name", Type.getType(String.class).getDescriptor(), null, null).visitEnd();

        cw.visitField(ACC_PUBLIC, "equal", "I", null, null).visitEnd();

        cw.visitField(ACC_PUBLIC, "grea", "I", null, null).visitEnd();

//        cw.visitMethod(ACC_PUBLIC, "compareTo", "(Ljava/lang/Object;)I", null, null).visitEnd();
        cw.visitMethod(1+ACC_ABSTRACT, "Comparable", "()V", null, null).visitEnd();

        cw.visitEnd();

        byte[] b = cw.toByteArray();

        MyClassLoader my = new MyClassLoader();

        Class c = my.defineClass("Comparable",b);
        AsmReader.reader(b);
        System.out.println(c.getMethods()[0].getName());

        Object a = c.newInstance();




    }
}
